package com.sinodata.bsm.center.engine.event.correlation;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.sinodata.bsm.center.engine.notify.NotifyEngine;
import com.sinodata.bsm.common.vo.Event;

/**
 * 
 * <p>
 * Description: 事件通知延迟器
 * </p>
 *
 * @author liulibo
 * @version 1.0

 * <p>
 * History: 
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * 2012-6-12 PM 1:37:00     liulibo        1.0         To create
 * </p>
 *
 * @since 
 * @see
 */
public class NotifyDelayer {
    private static NotifyDelayer instance = null;

    //需要延迟的事件列表
    private final List<Event> eventList = new ArrayList<Event>();
    //不需要通知的事件列表
    private final List<Event> noAlarmList = new ArrayList<Event>();
    //存储事件要延迟的时间
    private final Map<String, String> delayTimeMap = new HashMap<String, String>();
    //执行线程
    private DelayThread t = null;

    private NotifyDelayer() {
        init();
    }

    public static synchronized NotifyDelayer getInstance() {
        if (instance == null) {
            instance = new NotifyDelayer();
        }
        return instance;
    }

    /**
     * 检测事件是否要延迟通知
     */
    public boolean isNeedDelayed(Event event) {
        if (noAlarmList.contains(event)) {
            noAlarmList.remove(event);
            return true;
        }
        if (eventList.contains(event)) {
            return true;
        }
        return false;
    }

    //创建线程
    private void init() {
        t = new DelayThread();
        t.start();
    }

    /**
     * 添加需要延迟通知的事件
     * @param event
     * @param excuteTime
     */
    public void addEvent(Event event, long excuteTime) {
        //如果没有延迟时间不用加到列表中
        if (excuteTime <= 0) {
            return;
        }
        synchronized (eventList) {
            if (!eventList.contains(event)) {
                eventList.add(event);
                delayTimeMap.put(event.getId() + "", excuteTime + "");
            }
        }
    }

    //添加不需通知的事件
    public void addNoAlarmEvent(Event event) {
        noAlarmList.add(event);
    }

    /**
     * 删除需要延迟通知的事件
     * @param event
     * @param excuteTime
     */
    public void removeEvent(String id) {
        synchronized (eventList) {
            if (delayTimeMap.containsKey(id)) {
                delayTimeMap.remove(id);
                for (Event ev : eventList) {
                    if (id.equals(ev.getId() + "")) {
                        eventList.remove(ev);
                        return;
                    }
                }
            }
        }
    }

    //延迟线程
    class DelayThread extends Thread {
        //线程间隔时间
        private final int THREAD_INTERVAL = 10000;

        @Override
        public void run() {
            while (true) {
                //遍历一次暂停
                try {
                    Thread.sleep(THREAD_INTERVAL);
                } catch (InterruptedException e) {
                }
                //如果列表为空则暂停
                if (eventList == null || eventList.size() <= 0) {
                    continue;
                }
                //缓存要删除的事件
                List<Event> tempEventList = new ArrayList<Event>();
                //遍历事件列表，处理是否要通知
                synchronized (eventList) {
                    for (Event event : eventList) {
                        String delayTime = delayTimeMap.get(event.getId() + "");
                        long iDelayTime = -1;
                        try {
                            iDelayTime = Long.parseLong(delayTime);
                        } catch (Exception e) {
                            iDelayTime = -1;
                        }
                        if (iDelayTime < 0) {
                            tempEventList.add(event);
                            continue;
                        }
                        //如果延迟到时间了
                        if (iDelayTime <= 0 || System.currentTimeMillis() > iDelayTime) {
                            NotifyEngine.notify(event);
                            tempEventList.add(event);
                        }
                    }

                    //移除异常和已经通知的事件
                    for (Event event : tempEventList) {
                        eventList.remove(event);
                        delayTimeMap.remove(event.getId() + "");
                    }
                    tempEventList.clear();
                }
            }
        }
    }
}
